package com.pojoin.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayFundTransToaccountTransferRequest;
import com.alipay.api.response.AlipayFundTransToaccountTransferResponse;
import com.pojoin.common.dao.FileDao;
import com.pojoin.common.domain.FileDO;
import com.pojoin.common.utils.R;
import com.pojoin.system.dao.UserDao;
import com.pojoin.system.domain.UserDO;
import com.pojoin.system.service.MoneyHistoryService;
import com.pojoin.system.service.ShopmoneyService;
import io.swagger.models.auth.In;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import com.pojoin.system.dao.TixianDao;
import com.pojoin.system.domain.TixianDO;
import com.pojoin.system.service.TixianService;
import org.springframework.transaction.annotation.Transactional;


@Service
public class TixianServiceImpl implements TixianService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    //转账用次账号: 证书签名的方式
//支付宝公钥证书文件路径
    @Value("${ali.appid}")
    private String appid2;
    @Value("${alipaycertpath}")
    private String ALIPAY_CERT_PATH;
    //支付宝CA根证书文件路径
    @Value("${alipayrootcertpath}")
    private String ALIPAY_ROOT_CERT_PATH;
    //应用公钥证书路径
    @Value("${appcertpaht}")
    private String APP_CERT_PAHT;
    @Value("${ali.url}")
    private String URL;
    @Value("${appprivatekeycard}")
    private String APP_PRIVATE_KEY_CARD;
    @Value("${ALINOTIFY}")
    private String aliNotify;
    private static final String APP_ID = "2018012502067033";
    @Value("${ali.alipublickey}")
    private String ALIPAY_PUBLIC_KEY;
    @Value("${ali.appprivatekey}")
    String APP_PRIVATE_KEY;
    final String charset = "UTF-8";
    @Autowired
    private TixianDao tixianDao;
    @Autowired
    MoneyHistoryService moneyHistoryService;

    @Override
    public TixianDO get(Integer id) {
        return tixianDao.get(id);
    }

    @Override
    public List<TixianDO> list(Map<String, Object> map) {
        return tixianDao.list(map);
    }

    @Override
    public int count(Map<String, Object> map) {
        return tixianDao.count(map);
    }

    @Autowired
    UserDao userDao;
    @Autowired
    FileDao fileDao;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int save(TixianDO tixian) {
        Lock lock = new ReentrantLock();
        lock.lock();
        boolean flag = false;
        flag = check(Long.valueOf(tixian.getUserId().toString()), tixian.getMoney());
        if (!flag) {
            return 0;
        }
        saveCheck(Long.valueOf(tixian.getUserId().toString()), tixian.getMoney());
        try {
            if ("3".equals(tixian.getPayType())) {
                //银行卡 手动转账
                Double money = Double.valueOf(tixian.getMoney());
                userDao.updateMoney(-money, Long.valueOf(tixian.getUserId()));
                UserDO userDO = userDao.get(Long.valueOf(tixian.getUserId()));
                moneyHistoryService.addMoney(userDO.getUserId(), -Double.valueOf(tixian.getMoney()), 0d, userDO.getUserId(), "提现", "m", userDO.getMoney().toString(), userDO.getBalance().toString());
                fileDao.del(tixian.getUserId().toString(),tixian.getMoney());
                Double t = Double.valueOf(tixian.getMoney());
                //百分之3手续费
                t = t * 0.03;
                tixian.setMoney(String.valueOf(Double.valueOf(tixian.getMoney()) - t));
                return tixianDao.save(tixian);
            } else {
                Long userId = Long.valueOf(tixian.getUserId());
                //防重复提交校验
                UserDO userDO = userDao.get(userId);
                // 减去修改用户金额
                userDao.updateMoney(-Double.valueOf(tixian.getMoney()), userId);
                String outTradeNo = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + (int) (Math.random() * 90000 + 10000);
                //支付宝转账如果失败则联系平台手动转账

                String msg = "提现失败!";
                String s = zfbTransfer(outTradeNo, tixian.getAliPayAccount(), tixian.getBank2(), Double.valueOf(tixian.getMoney()));
                if (null == s) {
                    flag = true;
                    //更新用户的支付宝账号信息
                    UserDO userDO1 = new UserDO();
                    userDO1.setAliPayAccount(tixian.getAliPayAccount());
                    userDO1.setAliPayName(tixian.getBank2());
                    userDO1.setUserId(Long.valueOf(tixian.getUserId()));
                    userDao.update(userDO1);
                } else {
                    msg = s;
                    if (msg.contains("余额") || msg.contains("不足")) {
                        msg = "请用微信提现";
                    }
                    flag = false;
                }
                // 判断是否提现成功
                if (!flag) {
                    userDao.updateMoney(+Double.valueOf(tixian.getMoney()), userId);
                    fileDao.del(tixian.getUserId().toString(), tixian.getMoney());
                    return 0;
                }
                UserDO nowUser = userDao.get(userId);
                moneyHistoryService.addMoney(userDO.getUserId(), Double.valueOf(tixian.getMoney()), 0d, userDO.getUserId(), "提现", "m", nowUser.getMoney().toString(), nowUser.getBalance().toString());
                fileDao.del(tixian.getUserId().toString(),tixian.getMoney());
            }

            TixianDO tixianDO = new TixianDO();
            tixianDO.setUserId(tixian.getUserId());
            Double t = Double.valueOf(tixian.getMoney());
            //百分之3手续费
            t = t * 0.03;
            tixian.setMoney(String.valueOf(Double.valueOf(tixian.getMoney()) - t));
//            tixianDO.setMoney(tixian.getMoney());
            tixianDO.setStatus("1");
            tixianDO.setBank("支付宝");
            tixianDO.setAccout(tixian.getAliPayAccount());
            tixianDO.setCreatTime(new Date());
            tixianDO.setPayTime(new Date());
            tixianDO.setBank2(tixian.getBank2());
            tixianDao.save(tixianDO);

            return 1;
        } catch (Exception e) {
            return 0;
        } finally {
            lock.unlock();
        }


    }

    public void saveCheck(Long userId, String money) {
        FileDO fileDO = new FileDO();
        fileDO.setType(Integer.valueOf(userId.toString()));
        fileDO.setUrl(money);
        fileDao.save(fileDO);
    }

    public boolean check(Long userId, String money) {
        Map<String, Object> params = new HashMap<>();
        params.put("type", userId);
        params.put("url", money);
        int num = fileDao.count(params);
        if (num > 0) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 提现
     *
     * @param tixian
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int update(TixianDO tixian) {

        return tixianDao.update(tixian);
    }

    @Override
    public int remove(Integer id) {
        return tixianDao.remove(id);
    }

    @Override
    public int batchRemove(Integer[] ids) {
        return tixianDao.batchRemove(ids);
    }

    /**
     * @param
     * @return
     * @Description: 支付宝转账
     * @author: chenyu.zheng
     * @date: 2019/10/19 10:33 PM
     */
    private String zfbTransfer(String outTradeNo, String account, String realName, double money) throws Exception {
        //构造client
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("out_biz_no", outTradeNo);
        paramMap.put("payee_type", "ALIPAY_LOGONID");
        paramMap.put("payee_account", account);
        paramMap.put("amount", money);
        if (null != realName) {
            paramMap.put("payee_real_name", realName);
        }

        AlipayFundTransToaccountTransferRequest request = new AlipayFundTransToaccountTransferRequest();
        request.setBizContent(JSON.toJSONString(paramMap));
        AlipayFundTransToaccountTransferResponse response = getAlipayClient().certificateExecute(request);
        if (response.isSuccess()) {
            logger.info("<<<=======支付宝转账调用成功 msg :" + response.getMsg());
            return null;
        } else {
            logger.error("<<<=======支付宝转账调用失败 msg :" + response.getMsg());
            return response.getSubMsg();
        }
    }

    private AlipayClient getAlipayClient() {
        AlipayClient alipayClient = null;
        try {
            //构造client
            CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
            certAlipayRequest.setServerUrl(URL);
            certAlipayRequest.setAppId(appid2);
            certAlipayRequest.setPrivateKey(APP_PRIVATE_KEY_CARD);
            certAlipayRequest.setFormat("json");
            certAlipayRequest.setCharset("utf-8");
            certAlipayRequest.setSignType("RSA2");
            //设置应用公钥证书路径
            certAlipayRequest.setCertPath(APP_CERT_PAHT);
            //设置支付宝公钥证书路径
            certAlipayRequest.setAlipayPublicCertPath(ALIPAY_CERT_PATH);
            //设置支付宝根证书路径
            certAlipayRequest.setRootCertPath(ALIPAY_ROOT_CERT_PATH);
            alipayClient = new DefaultAlipayClient(certAlipayRequest);
        } catch (Exception e) {
            System.out.println("getAlipayClient is Exception" + e);
        }
        return alipayClient;
    }
}
